﻿using Application.ProductService;
using Application.ProductTypeService;
using Domain.Entity;
using Domain.Entity.bs;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using OfficeOpenXml;
using System.Linq;
using System.Text.Json;

namespace WMSManage.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]//需要鉴权
    public class ProductController : ControllerBase
    {
        private readonly IProductService productService;
        private readonly IDistributedCache distributedCache;

        public ProductController(IProductService productService, IDistributedCache distributedCache)
        {
            this.productService = productService;
            this.distributedCache = distributedCache;
        }


        /// <summary>
        /// 分页查询货品信息
        /// </summary>
        /// <param name="name">货品名称</param>
        /// <param name="inventory">是否有库存</param>
        /// <param name="type">货品类型名称</param>
        /// <param name="CurrentPage">当前页</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<FenYe<Product>> GetProduct(string? name, bool? inventory, string? type, int? whid, int CurrentPage)
        {
            FenYe<Product> fenYe = new FenYe<Product>()
            {
                CurrentPage = CurrentPage,
            };
            return await productService.GetProduct(fenYe, name, inventory, whid, type);
        }


        /// <summary>
        /// 刷新缓存
        /// </summary>
        /// <param name="name"></param>
        /// <param name="inventory"></param>
        /// <param name="type"></param>
        /// <param name="whid"></param>
        /// <param name="CurrentPage"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Refresh(string? name, bool? inventory, string? type, int? whid, int CurrentPage)
        {
            //缓存键
            string key = "product" + name + inventory + type + whid + CurrentPage;

            // 清除缓存键
            distributedCache.Remove(key);

            // 返回成功消息
            return Ok(new { success = true, message = "ok" });
        }


        /// <summary>
        /// 添加货品信息
        /// </summary>
        /// <param name="addProductDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<int> AddProduct(AddProductDto addProductDto)
        {
            return await productService.AddProduct(addProductDto);
        }


        /// <summary>
        /// 删除货品信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> DeleteProduct(int id)
        {
            return await productService.DeleteProduct(id);
        }


        /// <summary>
        /// 导入货品信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> ImportProduct()
        {
            //检查有没有文件
            var file = HttpContext.Request.Form.Files["file"];
            if (file == null || file.Length == 0)
            {
                return BadRequest(new { message = "未上传文件" });
            }

            try
            {
                using var stream = new MemoryStream();
                await file.CopyToAsync(stream);

                using var package = new ExcelPackage(stream);
                var worksheet = package.Workbook.Worksheets[0];

                if (worksheet.Dimension == null)
                {
                    return BadRequest(new { message = "Excel文件没有数据" });
                }

                int rowCount = worksheet.Dimension.Rows;
                int colCount = worksheet.Dimension.Columns;

                // 读取表头
                var headers = Enumerable.Range(1, colCount)
                    .Select(col => worksheet.Cells[1, col].Value?.ToString()?.Trim().ToLower())
                    .ToList();

                // 验证必要列是否存在
                if (!headers.Contains("货品编号"))
                {
                    return BadRequest(new { message = "Excel缺少'货品类型编号'列" });
                }

                // 获取所有已存在的货品类型编号和名称
                var existingProducts = await productService.GetAllProduct();//获取所有货品类型
                var existingCodes = existingProducts.Select(x => x.proc_code).ToList();//所有编号
                var existingNames = existingProducts.Select(x => x.proc_name).ToList();//所有名字

                var duplicateRows = new List<int>();
                var successCount = 0;
                var errorMessages = new List<string>();

                // 读取数据行
                for (int row = 2; row <= rowCount; row++)
                {
                    var rowData = new AddProductDto();
                    bool hasError = false;

                    for (int col = 1; col <= colCount; col++)
                    {
                        var header = headers[col - 1];
                        var value = worksheet.Cells[row, col].Value?.ToString()?.Trim();

                        try
                        {
                            // 赋值逻辑
                            switch (header)
                            {
                                case "货品编号":
                                    rowData.proc_code = value;
                                    break;
                                case "货品名称":
                                    rowData.proc_name = value;
                                    break;

                                // 状态管理
                                case "状态":
                                    rowData.proc_status = value == "启用" ? 0 : 1;
                                    break;
                                case "显示顺序":
                                    rowData.proc_status = Convert.ToInt32(value);
                                    break;

                                // 分类信息
                                case "货品类型":
                                    rowData.type_name = value;
                                    break;
                                case "货品类型编号":
                                    rowData.type_id = Convert.ToInt32(value);
                                    break;

                                // 规格信息
                                case "规格型号":
                                    rowData.proc_model = value;
                                    break;
                                case "单位":
                                    rowData.proc_primary_unit = value;
                                    break;
                                case "条码":
                                    rowData.proc_primary_barcode = value;
                                    break;

                                // 价格信息
                                case "入库参考价/元":
                                    rowData.instock_price = Convert.ToDouble(value);
                                    break;
                                case "出库参考价/元":
                                    rowData.outstock_price = Convert.ToDouble(value);
                                    break; 

                                // 保质期管理
                                case "保质期管理":
                                    rowData.is_datamanagement = value == "开启" ? 1 : 0;
                                    break;
                                case "保质期":
                                    rowData.proc_expirationdate = value;
                                    break;
                                case "预警天数":
                                    rowData.proc_Warningdays = Convert.ToInt32(value);
                                    break;

                                // 系统信息
                                case "操作人":
                                    rowData.create_name = value;
                                    break;
                                case "操作时间":
                                    rowData.create_time = value;
                                    break;
                                case "备注":
                                    rowData.remark = value;
                                    break;
                            }
                        }
                        catch (Exception ex)
                        {
                            errorMessages.Add($"第{row}行数据格式错误: {ex.Message}");
                            hasError = true;
                            break;
                        }
                    }

                    if (hasError) continue;

                    // 检查是否已存在（更严格的检查）
                    if (existingCodes.Contains(rowData.proc_code))
                    {
                        duplicateRows.Add(row);
                        errorMessages.Add($"第{row}行数据导入失败: 货品类型编号 {rowData.proc_code} 已存在");
                        continue;
                    }

                    var result = await productService.AddProduct(rowData);
                    if (result <0)
                    {
                        errorMessages.Add($"第{row}行数据导入失败");
                    }
                    else
                    {
                        successCount++;
                        existingCodes.Add(rowData.proc_code); // 更新缓存
                    }
                }

                return Ok(new
                {
                    successCount,
                    duplicateCount = duplicateRows.Count,
                    duplicateRows,
                    errors = errorMessages
                });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { message = "处理文件时出错", error = ex.Message });
            }
        }


        /// <summary>
        /// 根据id查询货品信息
        /// </summary>
        /// <param name="id">货品id</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Product> GetProductById(int id)
        {
            return await productService.GetProductById(id);
        }



        /// <summary>
        /// 修改货品信息
        /// </summary>
        /// <param name="updateProductDto"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> UpdateProduct(UpdateProductDto updateProductDto)
        {
            return await productService.UpdateProduct(updateProductDto);
        }



        /// <summary>
        /// 修改货品信息状态（启用/停用）
        /// </summary>
        /// <param name="procid">货品id</param>
        /// <param name="status">状态0：1</param>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> UpdateStatus(int procid, int status)
        {
            return await productService.UpdateStatus(procid, status);
        }




        /// <summary>
        /// 分页高级查询
        /// </summary>
        /// <param name="code"></param>
        /// <param name="name"></param>
        /// <param name="typeid"></param>
        /// <param name="model"></param>
        /// <param name="unit"></param>
        /// <param name="startinprice"></param>
        /// <param name="endinprice"></param>
        /// <param name="startoutprice"></param>
        /// <param name="endoutprice"></param>
        /// <param name="is_datamanagement"></param>
        /// <param name="status"></param>
        /// <param name="startwarningdays"></param>
        /// <param name="endwarningdays"></param>
        /// <param name="whid"></param>
        /// <param name="barcode"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="createname"></param>
        /// <returns></returns>
        [HttpGet]
        //分页高级查询
        public async Task<FenYe<Product>> GetAdvancedProduct(string? code, string? name, string? typeid, string? model, string? unit, string? startinprice, string? endinprice, string? startoutprice, string? endoutprice, int? is_datamanagement, int? status, int? startwarningdays, int? endwarningdays, int? whid, string? barcode, string? starttime, string? endtime, string? createname,int CurrentPage)
        {
            FenYe<Product> fenYe = new FenYe<Product>()
            {
                CurrentPage = CurrentPage,
            };
            return await productService.GetAdvancedProduct(fenYe,code, name, typeid, model, unit, startinprice, endinprice, startoutprice,endoutprice, is_datamanagement, status, startwarningdays, endwarningdays, whid, barcode, starttime,endtime,createname);
        }



        /// <summary>
        /// 修改货品计划可用库存
        /// </summary>
        /// <param name="id"></param>
        /// <param name="inventory"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<int> Updateky(int id, int inventory)
        {
            return await productService.Updateky(id, inventory);
        }

        /// <summary>
        /// 根据库存查货物
        /// </summary>
        /// <param name="CurrentPage"></param>
        /// <param name="wh_id"></param>
        /// <param name="proc_code"></param>
        /// <param name="proc_primary_unit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<FenYe<ProductWithStocks>> GetProductsByIds(int CurrentPage, int wh_id, string? proc_code = null, string? proc_primary_unit = null)
        {
            return await productService.GetProductsByIds(CurrentPage, wh_id, proc_code, proc_primary_unit);
        }

        /// <summary>
        /// 根据货品id批量获取
        /// </summary>
        /// <param name="proc_ids"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<Product>> GetPIds([FromQuery] int[] proc_ids)
        {
            return await productService.GetProductsByIds(proc_ids);  
        }
    }
}
